﻿// -----------------------------------------------------------------------
// <copyright file="GaussianFilter.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace ImageP
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using MathWorks.MATLAB.NET.Arrays;
    using MathWorks.MATLAB.NET.Utility;
    using System.Data;
    using FourierFin;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class GaussianFilter
    {
        Normalize norm = new Normalize();
  

        public int[,] normalizedBufferRed;
        public int[,] normalizedBufferGreen;
        public int[,] normalizedBufferBlue;
        
       
        private int width;
        private int height;
        public double[,] D;
        public double[,] H;

        public double[,] RealRed;
        public double[,] RealGreen;
        public double[,] RealBlue;

        public double[,] ImaginaryRed;
        public double[,] ImaginaryGreen;
        public double[,] ImaginaryBlue;

      public  Bitmap bm;
      public RGBcolor[,] realImage;
      public FourierT ft = new FourierT();
      public MWArray realF;
      public double[,] realBufferR, realBufferG, realBufferB, imgBufferR, imgBufferG, imgBufferB;

      public void get(Bitmap Buffer)
      {
          byte[,] R = new byte[Buffer.Height, Buffer.Width];
          byte[,] G = new byte[Buffer.Height, Buffer.Width];
          byte[,] B = new byte[Buffer.Height, Buffer.Width];
          Color Clr;

          for (int i = 0; i < Buffer.Height; i++)
          {
              for (int j = 0; j < Buffer.Width; j++)
              {
                  Clr = Buffer.GetPixel(j, i);
                  R[i, j] = Clr.R;
                  G[i, j] = Clr.G;
                  B[i, j] = Clr.B;
              }
          }
          MWArray ftsR, ftsG, ftsB;
          ftsR = (MWNumericArray)ft.FreqDomian((MWNumericArray)R);
          ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
          ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

          realBufferR = (double[,])ft.getReal(ftsR).ToArray();
          realBufferG = (double[,])ft.getReal(ftsG).ToArray();
          realBufferB = (double[,])ft.getReal(ftsB).ToArray();

          imgBufferR = (double[,])ft.getImag(ftsR).ToArray();
          imgBufferG = (double[,])ft.getImag(ftsG).ToArray();
          imgBufferB = (double[,])ft.getImag(ftsB).ToArray();
      }

        public void ConstructFilterBuffer(double D0,int width,int height,int type)
        {
            this.width = width;
            this.height = height;
            H = new double[this.height, this.width];
            D = new double[this.height, this.width];
            for (int i = 0; i < this.height; i++)
            {
                for (int j = 0; j < this.width; j++)
                {
                    D[i, j] = Math.Sqrt(Math.Pow((j - (this.width / 2)), 2) + Math.Pow((i - (this.height/ 2)), 2));
                }
                
            }
            if (type == 1)
            {
                for (int i = 0; i < this.height; i++)
                {
                    for (int j = 0; j < this.width; j++)
                    {
                        H[i, j] = Math.Exp(-(Math.Pow(D[i, j], 2) / (2 * Math.Pow(D0, 2))));
                     
                    }

                }
            }

            else if (type == 2)
            {
                for (int i = 0; i < this.height; i++)
                {
                    for (int j = 0; j < this.width; j++)
                    {
                        H[i, j] = 1-(Math.Exp(-(Math.Pow(D[i, j], 2) / (2 * Math.Pow(D0, 2)))));
                    }

                }
            }
            
        }
       

        public Bitmap getInverse()
        {
            MWArray inverseFreqR, inverseFreqG, inverseFreqB;
            double[,] realR, realG, realB;
            bm = new Bitmap(width, height);
            inverseFreqR = (MWArray)ft.InvF((MWNumericArray)(RealRed), (MWNumericArray)ImaginaryRed);
            inverseFreqG = (MWArray)ft.InvF((MWNumericArray)RealGreen, (MWNumericArray)ImaginaryGreen);
            inverseFreqB = (MWArray)ft.InvF((MWNumericArray)RealBlue, (MWNumericArray)ImaginaryBlue);
            realR = (double[,])inverseFreqR.ToArray();
            realG = (double[,])inverseFreqG.ToArray();
            realB = (double[,])inverseFreqB.ToArray();
            normalizedBufferRed = new int[this.height, this.width];
            normalizedBufferGreen = new int[this.height, this.width];
            normalizedBufferBlue = new int[this.height, this.width];
            //normalizedBufferRed.Initialize();
            //normalizedBufferGreen.Initialize();
            //normalizedBufferBlue.Initialize();
            //for (int i = 0; i < this.height; i++)
            //{
            //    for (int j = 0; j < this.width; j++)
            //    {
            //        if (realR[i, j] < 0)
            //            normalizedBufferRed[i, j] = 0;
            //        else if (realR[i, j] > 255)
            //            normalizedBufferRed[i, j] = 255;
         
            //for (int i = 0; i < this.height; i++)
            //{
            //    for (int j = 0; j < this.width; j++)
            //    {
            //        if (realR[i, j] < 0)
            //            normalizedBufferRed[i, j] = 0;
            //        else if (realR[i, j] > 255)
            //            normalizedBufferRed[i, j] = 255;

            //        if (realG[i, j] < 0)
            //            normalizedBufferGreen[i, j] = 0;
            //        else if (realG[i, j] > 255)
            //            normalizedBufferGreen[i, j] = 255;

            //        if (realB[i, j] < 0)
            //            normalizedBufferBlue[i, j] = 0;
            //        else if (realB[i, j] > 255)
            //            normalizedBufferBlue[i, j] = 255;

            //    }
            //}
            normalizedBufferRed = norm.Normalize_imagefft(realR, this.height, this.width);
            normalizedBufferGreen = norm.Normalize_imagefft(realG, this.height, this.width);
            normalizedBufferBlue = norm.Normalize_imagefft(realB, this.height, this.width);
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        bm.SetPixel(j, i, System.Drawing.Color.FromArgb(normalizedBufferRed[i, j], normalizedBufferGreen[i, j], normalizedBufferBlue[i, j]));
                    }
                }
            return bm;
        }


        public void getRealGaussian()
        {
            RealRed = new double[this.height, this.width];
            RealGreen = new double[this.height, this.width];
            RealBlue = new double[this.height, this.width];

            for (int i = 0; i < this.height; i++)
			{
			 for (int j = 0; j < this.width; j++)
			 {
               RealRed[i,j]=realBufferR[i, j] * H[i, j];
               RealGreen[i, j] = realBufferG[i, j] * H[i, j];
               RealBlue[i, j] =realBufferB[i, j] * H[i, j];
			 }
			}
           
            
        }

        public void getImaginaryGaussian()
        {
            ImaginaryRed = new double[this.height, this.width];
            ImaginaryGreen = new double[this.height, this.width];
            ImaginaryBlue = new double[this.height, this.width];

            for (int i = 0; i < this.height; i++)
            {
                for (int j = 0; j < this.width; j++)
                {
                    ImaginaryRed[i, j] = imgBufferR[i, j] * H[i, j];
                    ImaginaryGreen[i, j] = imgBufferG[i, j] * H[i, j];
                    ImaginaryBlue[i, j] = imgBufferB[i, j] * H[i, j];
                }
            }
        }



    }
}
